From: awilliam@xenbuild.aw Date: Wed, 12 Jul 2006 19:20:15 +0000 (-0600) Subject: [IA64] enable acceleration of external interrupt X-Git-Tag: archive/raspbian/4.8.0-1+rpi1~1^2~15786^2~28 X-Git-Url: https://dgit.raspbian.org/%22http://www.example.com/cgi/success//%22http:/www.example.com/cgi/success/?a=commitdiff_plain;h=bf0c9d92ab651b73c5e98b7f8276142b61e8151c;p=xen.git [IA64] enable acceleration of external interrupt This patch is to enable acceleration of externel interrupt which is described in VTI spec. Signed-off-by: Anthony Xu --- diff --git a/xen/arch/ia64/vmx/pal_emul.c b/xen/arch/ia64/vmx/pal_emul.c index 8fcdf21bbc..4857dba00a 100644 --- a/xen/arch/ia64/vmx/pal_emul.c +++ b/xen/arch/ia64/vmx/pal_emul.c @@ -146,7 +146,7 @@ static struct ia64_pal_retval pal_halt_light(VCPU *vcpu) { struct ia64_pal_retval result; - if (SPURIOUS_VECTOR == vmx_check_pending_irq(vcpu)) + if (!is_unmasked_irq(vcpu)) do_sched_op_compat(SCHEDOP_block, 0); INIT_PAL_STATUS_SUCCESS(result); diff --git a/xen/arch/ia64/vmx/vlsapic.c b/xen/arch/ia64/vmx/vlsapic.c index 749607d8eb..3f105ce312 100644 --- a/xen/arch/ia64/vmx/vlsapic.c +++ b/xen/arch/ia64/vmx/vlsapic.c @@ -289,7 +289,7 @@ static void update_vhpi(VCPU *vcpu, int vec) vhpi = 16; } else { - vhpi = vec / 16; + vhpi = vec >> 4; } VCPU(vcpu,vhpi) = vhpi; @@ -436,7 +436,7 @@ static int highest_inservice_irq(VCPU *vcpu) */ static int is_higher_irq(int pending, int inservice) { - return ( (pending >> 4) > (inservice>>4) || + return ( (pending > inservice) || ((pending != NULL_VECTOR) && (inservice == NULL_VECTOR)) ); } @@ -460,7 +460,6 @@ static int _xirq_masked(VCPU *vcpu, int h_pending, int h_inservice) { tpr_t vtpr; - uint64_t mmi; vtpr.val = VCPU(vcpu, tpr); @@ -474,9 +473,9 @@ _xirq_masked(VCPU *vcpu, int h_pending, int h_inservice) if ( h_inservice == ExtINT_VECTOR ) { return IRQ_MASKED_BY_INSVC; } - mmi = vtpr.mmi; + if ( h_pending == ExtINT_VECTOR ) { - if ( mmi ) { + if ( vtpr.mmi ) { // mask all external IRQ return IRQ_MASKED_BY_VTPR; } @@ -486,7 +485,7 @@ _xirq_masked(VCPU *vcpu, int h_pending, int h_inservice) } if ( is_higher_irq(h_pending, h_inservice) ) { - if ( !mmi && is_higher_class(h_pending, vtpr.mic) ) { + if ( is_higher_class(h_pending, vtpr.mic + (vtpr.mmi << 4)) ) { return IRQ_NO_MASKED; } else { @@ -577,6 +576,8 @@ int vmx_check_pending_irq(VCPU *vcpu) isr = vpsr.val & IA64_PSR_RI; if ( !vpsr.ic ) panic_domain(regs,"Interrupt when IC=0\n"); + if (VCPU(vcpu, vhpi)) + update_vhpi(vcpu, NULL_VECTOR); vmx_reflect_interruption(0,isr,0, 12, regs ); // EXT IRQ } else if ( mask == IRQ_MASKED_BY_INSVC ) { @@ -612,6 +613,20 @@ void guest_write_eoi(VCPU *vcpu) // vmx_check_pending_irq(vcpu); } +int is_unmasked_irq(VCPU *vcpu) +{ + int h_pending, h_inservice; + + h_pending = highest_pending_irq(vcpu); + h_inservice = highest_inservice_irq(vcpu); + if ( h_pending == NULL_VECTOR || + irq_masked(vcpu, h_pending, h_inservice) != IRQ_NO_MASKED ) { + return 0; + } + else + return 1; +} + uint64_t guest_read_vivr(VCPU *vcpu) { int vec, h_inservice; @@ -628,7 +643,8 @@ uint64_t guest_read_vivr(VCPU *vcpu) VLSAPIC_INSVC(vcpu,vec>>6) |= (1UL <<(vec&63)); VCPU(vcpu, irr[vec>>6]) &= ~(1UL <<(vec&63)); - update_vhpi(vcpu, NULL_VECTOR); // clear VHPI till EOI or IRR write + if (VCPU(vcpu, vhpi)) + update_vhpi(vcpu, NULL_VECTOR); // clear VHPI till EOI or IRR write local_irq_restore(spsr); return (uint64_t)vec; } diff --git a/xen/arch/ia64/vmx/vmx_init.c b/xen/arch/ia64/vmx/vmx_init.c index 074c536f56..8cd3501ed9 100644 --- a/xen/arch/ia64/vmx/vmx_init.c +++ b/xen/arch/ia64/vmx/vmx_init.c @@ -183,7 +183,8 @@ static vpd_t *alloc_vpd(void) mregs->vac.a_from_cpuid = 1; mregs->vac.a_cover = 1; mregs->vac.a_bsw = 1; - + mregs->vac.a_int = 1; + mregs->vdc.d_vmsw = 1; return vpd; diff --git a/xen/arch/ia64/vmx/vmx_process.c b/xen/arch/ia64/vmx/vmx_process.c index 857195942b..763c11d10b 100644 --- a/xen/arch/ia64/vmx/vmx_process.c +++ b/xen/arch/ia64/vmx/vmx_process.c @@ -35,7 +35,7 @@ #include #include #include -//#include +#include #include #include #include @@ -188,13 +188,13 @@ void leave_hypervisor_tail(struct pt_regs *regs) struct vcpu *v = current; // FIXME: Will this work properly if doing an RFI??? if (!is_idle_domain(d) ) { // always comes from guest - extern void vmx_dorfirfi(void); - struct pt_regs *user_regs = vcpu_regs(current); +// struct pt_regs *user_regs = vcpu_regs(current); + local_irq_enable(); do_softirq(); local_irq_disable(); - if (user_regs != regs) - printk("WARNING: checking pending interrupt in nested interrupt!!!\n"); +// if (user_regs != regs) +// printk("WARNING: checking pending interrupt in nested interrupt!!!\n"); /* VMX Domain N has other interrupt source, saying DM */ if (test_bit(ARCH_VMX_INTR_ASSIST, &v->arch.arch_vmx.flags)) @@ -215,12 +215,18 @@ void leave_hypervisor_tail(struct pt_regs *regs) if ( v->arch.irq_new_pending ) { v->arch.irq_new_pending = 0; + v->arch.irq_new_condition = 0; vmx_check_pending_irq(v); + return; + } + if (VCPU(v, vac).a_int) { + vhpi_detection(v); + return; + } + if (v->arch.irq_new_condition) { + v->arch.irq_new_condition = 0; + vhpi_detection(v); } -// if (VCPU(v,vac).a_bsw){ -// save_banked_regs_to_vpd(v,regs); -// } - } } diff --git a/xen/arch/ia64/vmx/vmx_virt.c b/xen/arch/ia64/vmx/vmx_virt.c index c1fabd45ff..08d6683f58 100644 --- a/xen/arch/ia64/vmx/vmx_virt.c +++ b/xen/arch/ia64/vmx/vmx_virt.c @@ -30,7 +30,6 @@ #include #include #include -extern void vhpi_detection(VCPU *vcpu);//temporarily place here,need a header file. void ia64_priv_decoder(IA64_SLOT_TYPE slot_type, INST64 inst, UINT64 * cause) @@ -1342,14 +1341,6 @@ IA64FAULT vmx_emul_mov_from_cr(VCPU *vcpu, INST64 inst) } -static void post_emulation_action(VCPU *vcpu) -{ - if ( vcpu->arch.irq_new_condition ) { - vcpu->arch.irq_new_condition = 0; - vhpi_detection(vcpu); - } -} - //#define BYPASS_VMAL_OPCODE extern IA64_SLOT_TYPE slot_types[0x20][3]; IA64_BUNDLE __vmx_get_domain_bundle(u64 iip) @@ -1552,8 +1543,6 @@ if ( (cause == 0xff && opcode == 0x1e000000000) || cause == 0 ) { } recover_if_physical_mode(vcpu); - post_emulation_action (vcpu); -//TODO set_irq_check(v); return; } diff --git a/xen/include/asm-ia64/vmx_vcpu.h b/xen/include/asm-ia64/vmx_vcpu.h index 90eb33fd15..d77805d4d6 100644 --- a/xen/include/asm-ia64/vmx_vcpu.h +++ b/xen/include/asm-ia64/vmx_vcpu.h @@ -103,6 +103,7 @@ extern void vtm_interruption_update(VCPU *vcpu, vtime_t* vtm); extern void vlsapic_reset(VCPU *vcpu); extern int vmx_check_pending_irq(VCPU *vcpu); extern void guest_write_eoi(VCPU *vcpu); +extern int is_unmasked_irq(VCPU *vcpu); extern uint64_t guest_read_vivr(VCPU *vcpu); extern void vmx_inject_vhpi(VCPU *vcpu, u8 vec); extern int vmx_vcpu_pend_interrupt(VCPU *vcpu, uint8_t vector);